﻿using System;

namespace DevOnServer
{
    public struct CVec3Df
    {
        public CVec3Df(float x = 0f, float y = 0f, float z = 0f)
        {
            X = x;
            Y = y;
            Z = z;
        }

        public float X, Y, Z;

        public float Length
        {
            get
            {
                return (float)Math.Sqrt(X * X + Y * Y + Z * Z);
            }
        }

        public float LengthSq
        {
            get
            {
                return X * X + Y * Y + Z * Z;
            }
        }

        public bool isInRange(CVec3Df v, float range)
        {
            return (v - this).LengthSq <= (range * range);
        }

        public bool isInRangeSq(CVec3Df v, float range)
        {
            return (v - this).LengthSq <= range;
        }

        public float Length2D
        {
            get
            {
                return (float)Math.Sqrt(X * X + Z * Z);
            }
        }

        public float LengthSq2D
        {
            get
            {
                return X * X + Z * Z;
            }
        }

        public bool isInRange2D(CVec3Df v, float range)
        {
            return (v - this).LengthSq2D <= (range * range);
        }

        public bool isInRangeSq2D(CVec3Df v, float range)
        {
            return (v - this).LengthSq2D <= range;
        }

        public static CVec3Df operator -(CVec3Df vec1, CVec3Df vec2)
        {
            return new CVec3Df(vec1.X - vec2.X, vec1.Y - vec2.Y, vec1.Z - vec2.Z);
        }

        public static CVec3Df operator +(CVec3Df vec1, CVec3Df vec2)
        {
            return new CVec3Df(vec1.X + vec2.X, vec1.Y + vec2.Y, vec1.Z + vec2.Z);
        }

        public static CVec3Df operator /(CVec3Df v, float f)
        {
            return new CVec3Df(v.X / f, v.Y / f, v.Z / f);
        }

        public static CVec3Df operator *(CVec3Df v, float f)
        {
            return new CVec3Df(v.X * f, v.Y * f, v.Z * f);
        }

        public static bool operator <=(CVec3Df vec1, CVec3Df vec2)
        {
            return vec1.X <= vec2.X && vec1.Y <= vec2.Y && vec1.Z <= vec2.Z;
        }

        public static bool operator >=(CVec3Df vec1, CVec3Df vec2)
        {
            return vec1.X >= vec2.X && vec1.Y >= vec2.Y && vec1.Z >= vec2.Z;
        }

        public static bool operator ==(CVec3Df vec, float f)
        {
            return vec.X - 0.000001f < f && vec.X + 0.000001f > f
                && vec.Y - 0.000001f < f && vec.Y + 0.000001f > f
                && vec.Z - 0.000001f < f && vec.Z + 0.000001f > f;
        }

        public static bool operator !=(CVec3Df vec, float f)
        {
            return !(vec == f);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            return base.Equals(obj);
        }
    }
}